import HelperFunctions as HF
import numpy as np
from numpy import array
from scipy import linalg
from datetime import datetime
from time import strftime
import random
import csv

'''
add a field to identify the cancer in population point shapefile

***revision of test11.py***
randomly choose the point from shapefile to add cancer
'''

def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def get_inputs():
    """Given the list of inputs for the script when run, return an object
    containing the variables for the script"""
    try:
        sInputFC = "C:\oneMillionTP1000.shp"  # population point data
        inputCSV = "C:\oneMillionTP1000.csv"  # Thessien Polygon ID
        areaID = "FID_2"  # the field name of high/low risk polygon id

  
    except: raise HF.ReportError (HF.msgParseErr)
    
    #Make a generic object, populate it with our variables, then return it
    try:
        obj = HF.Gen()
        obj.add('sInputFC',sInputFC)
        obj.add('inputCSV',inputCSV)
        obj.add('areaID',areaID)
        #obj.add('sOutputFC', sOutputFC)

    except: raise HF.ReportError (HF.msgInputsErr)

    return obj

def build_value_lists():
    # build a cancer list
    print "===========start build value list============"
    pRows = HF.pGP.SearchCursor(inputs.sInputFC)
    pRow = pRows.Next()
    areaData = []   # [[FID,AreaID,Cancer],...]
    iError = 0
    
    while pRow <> None:
        try:            
            areaData.append([int(pRow.GetValue("FID")),int(pRow.GetValue(inputs.areaID)),0])  
        except:
            iError = iError + 1
        pRow = pRows.Next()

    print "Error = ", iError    

    return areaData

def build_value_lists_csv():
    #data = np.array([],dtype=int)
    data = []
    #regionData = []
    fn = inputCSV
    #ra = csv.DictReader(file(fn), dialect="excel")
    ra = csv.reader(open(fn, 'U'), delimiter=' ', quotechar='|')
    i = 0
    for record in ra:
        #print record, type(record[0])
        #regionData.append(int(float(record[0])))
        data.append(int(float(record[0])))
        i = i + 1
        #data = np.append(data, int(float(record[0])))
    #areaData.shape=(-1,2)
    return data

def cal_cancer_case(iLen):
    #add cancer to list areaData
    #print "========================Add Cancer============================="
    #incidence = [0.010,0.015,0.005,0.015,0.015,0.005,0.005,0.015]

    #[average rate, high rate, low rate]    
    incidence = [0.010,0.015,0.005]
    
    sigma = [0.0010,0.0010,0.0010,0.0010,0.0010,0.0010,0.0010,0.0010]

    #polygon id within high risk area 
    HighAreaID = [8,16,844,915,919,921,923,924,63,265,267,268,333,336,337,339,340,342,343,348,13,174,178,198,886,887,888,889,890,69,70,87,88,369,370,372,442,443]
    
    #polygon id within low risk area 
    LowAreaID = [5,103,106,513,517,518,520,531,534,535,536,541,146,171,182,810,811,814,815,864,867,20,133,692,694,695,696,698,702,705]
    TotalPop = len(areaData)
    #print TotalPop
    #cancer = 0 #total of cancer case
    i = 0
    regCancer = np.fromfunction(generate_zero_list, (iLen,))
    
    while i < TotalPop:
        # if the point is within the high risk area
        if int(areaData[i]) in HighAreaID:
            iIncidence = 1
        #if the point is within the low risk area
        elif int(areaData[i]) in LowAreaID:
            iIncidence = 2
        else:
            iIncidence = 0
        #iIncidence = areaData[i][1]
        tempIncidence = np.random.normal(incidence[iIncidence], sigma[iIncidence], 1)
        if np.random.random() < tempIncidence[0]:
            #areaData[i][2] = 1
            regCancer[int(areaData[i])] = regCancer[int(areaData[i])] + 1  #total of cancer case
        i = i + 1
    return regCancer

def add_cancer():
    #add cancer to list areaData
    print "========================Add Cancer============================="
    #incidence = [0.010,0.015,0.005,0.015,0.015,0.005,0.005,0.015]

    #[average rate, high rate, low rate]    
    incidence = [0.010,0.015,0.005]
    
    sigma = [0.0010,0.0010,0.0010,0.0010,0.0010,0.0010,0.0010,0.0010]

    #polygon id within high risk area 
    HighAreaID = [8,16,844,915,919,921,923,924,63,265,267,268,333,336,337,339,340,342,343,348,13,174,178,198,886,887,888,889,890,69,70,87,88,369,370,372,442,443]

    #polygon id within low risk area 
    LowAreaID = [5,103,106,513,517,518,520,531,534,535,536,541,146,171,182,810,811,814,815,864,867,20,133,692,694,695,696,698,702,705]
    TotalPop = len(areaData)
    cancer = 0 #total of cancer case
    i = 0
    while i < TotalPop:
        # if the point is within the high risk area
        if areaData[i][1] in HighAreaID:
            iIncidence = 1
        #if the point is within the low risk area
        elif areaData[i][1] in LowAreaID:
            iIncidence = 2
        else:
            iIncidence = 0
        #iIncidence = areaData[i][1]
        tempIncidence = np.random.normal(incidence[iIncidence], sigma[iIncidence], 1)
        if np.random.random() < tempIncidence[0]:
            areaData[i][2] = 1
            cancer = cancer + 1  #total of cancer case
        i = i + 1
    #print areaData
    print "cancer = ", cancer

def output_results(outField):
    """ This function writes results to the output feature class. """
    
    # Add results field.
    #HF.pGP.AddMessage ("--------" + getCurTime() + "--------")
    #HF.pGP.AddMessage ("Updating results fields...")
    #addField = []
    print "========================================================"    

    #added field name    
    #outField = "Cancer"
    #if properties.dcFields.has_key(outField.upper()):
        #HF.pGP.deletefield(inputs.sInputFC, outField) 
    HF.pGP.AddField(inputs.sInputFC, outField, "SHORT")
        
    # Add results to output FC
    #HF.pGP.AddMessage ("--------" + getCurTime() + "--------")
    #HF.pGP.AddMessage (HF.sWritingResults)
    pRows = HF.pGP.UpdateCursor(inputs.sInputFC)
    pRow = pRows.Next()
    iError = 0
    iCnt = 0
    fInterval = 1000000 / 5.0
    fMore = fInterval
    iComplete = 20


    while pRow <> None:
        iKey = pRow.GetValue("FID")

        try:
            pRow.SetValue(outField, areaData[iKey][2])
            pRows.UpdateRow(pRow)
            iCnt = iCnt + 1
            if iCnt > fInterval: fInterval, iComplete = HF.check_progress(fInterval, fMore, iComplete)
        
        except:
            iError = iError + 1
        
        pRow = pRows.Next()
        

    #print "++++++++++++++++++++++"
    print "Error = ", iError
    
        
    HF.pGP.AddMessage (HF.s100Percent)
    HF.pGP.AddMessage(" ")
    pRows = None           
    #return sField  

def generate_zero_list(i):
    return i-i

#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    print "======================================================="
    print "begin at " + getCurTime()
    #inputs = get_inputs()
    sInputFC = "C:\oneMillionTP1000.shp"  # population point data
    inputCSV = "C:\oneMillionTP1000.csv"  # Thessien Polygon ID
    areaID = "FID_2"  # the field name of high/low risk polygon id
    #print inputs.sInputFC
    
    #properties = HF.get_featureclass_properties(inputs.sInputFC)
    areaData = build_value_lists_csv()
    dis_reg = set(areaData)
    #del regionData
    #regCancer = np.fromfunction(generate_zero_list, (len(dis_reg)))
    regCancerT = np.arange(0, len(dis_reg), 1)
    
    i = 0
    iterNum = 1000
    while i < iterNum:
        print i
        i = i + 1
        #for item in areaData:
            #item[2] = 0
        #temp = str(i)
        #outField = "cancer" + temp
        #print outField
        random.shuffle(areaData)
        temp = cal_cancer_case(len(dis_reg))                               
        regCancerT = np.append(regCancerT, temp)
    regCancerT.shape = (iterNum + 1, -1)
    #temp = regCancerT.transpose
    temp = np.transpose(regCancerT)
    #print temp
    np.savetxt("C:/temp.txt", temp, delimiter=',')
    
    print "end at " + getCurTime()
